using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Be.Timvw.Framework.Domain.Ranges
{
    [TestClass]
    public class WhenDeterminingIfDateTimeRangeIsCovered
    {
        [TestMethod]
        public void ShouldReturnTrueWhenPeriodIsFullyCovered()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(2008, 12, 31, 23, 59, 59));

            IEnumerable<DateTimeRange> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(2009, 1, 1, 23, 59, 59))
                };

            Assert.IsTrue(periodToCover.IsCoveredBy(coveredPeriods));
        }

        [TestMethod]
        public void ShouldReturnFalseWhenPeriodIsNotFullyCovered()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(2008, 12, 31, 23, 59, 59));

            IEnumerable<DateTimeRange> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2010, 1, 1), new DateTime(2010, 12, 31, 23, 59, 59))
                };

            Assert.IsFalse(periodToCover.IsCoveredBy(coveredPeriods));
        }

        [TestMethod]
        public void ShouldReturnTrueWhenCoveredTillEndOfTime()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 59));

            IEnumerable<DateTimeRange> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(2009, 1, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2009, 1, 2), new DateTime(9999, 12, 31, 23, 59, 59))
                };

            Assert.IsTrue(periodToCover.IsCoveredBy(coveredPeriods));
        }

        [TestMethod]
        public void ShouldReturnFalseWhenNotCoveredTillEndOfTime()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 59));

            IEnumerable<DateTimeRange> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(2009, 1, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2009, 1, 2), new DateTime(9999, 12, 31, 23, 59, 58))
                };

            Assert.IsFalse(periodToCover.IsCoveredBy(coveredPeriods));
        }

        [TestMethod]
        public void ShouldReturnTrueWhenCoveredTillEndOfTimeEvenWithBoundaryElement()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 59));

            IEnumerable<DateTimeRange> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 58)),
                new DateTimeRange(new DateTime(9999, 12, 31, 23, 59, 59), new DateTime(9999, 12, 31, 23, 59, 59))
                };

            Assert.IsTrue(periodToCover.IsCoveredBy(coveredPeriods));
        }

        [TestMethod]
        public void ShouldReturnTrueWhenCoveredTillEndOfTimeEvenWithBoundaryElements()
        {
            DateTimeRange periodToCover = new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 59));

            IEnumerable<IDiscreteValuesRange<DateTime>> coveredPeriods = new DateTimeRange[]
                {
                new DateTimeRange(new DateTime(2000, 1, 1), new DateTime(2008, 6, 1, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 6, 2), new DateTime(2008, 6, 30, 23, 59, 59)),
                new DateTimeRange(new DateTime(2008, 1, 1), new DateTime(9999, 12, 31, 23, 59, 57)),
                new DateTimeRange(new DateTime(9999, 12, 31, 23, 59, 58), new DateTime(9999, 12, 31, 23, 59, 58)),
                new DateTimeRange(new DateTime(9999, 12, 31, 23, 59, 59), new DateTime(9999, 12, 31, 23, 59, 59))
                };

            Assert.IsTrue(periodToCover.IsCoveredBy(coveredPeriods));
        }
    }
}